package com.titan.core.utils.data;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

/**
 * @author 周成功
 * @email 86898837@qq.com
 * @date 2020年02月15日
 */
public class RegexUtils {
    public final static Pattern GROUP_VAR =  Pattern.compile("\\$(\\d+)", Pattern.DOTALL);
    /** 正则中需要被转义的关键字 */
    public final static Set<Character> RE_KEYS = SetUtils.toSet('$', '(', ')', '*', '+', '.', '[', ']', '?', '\\', '^', '{', '}', '|');

    
    
    public static boolean isMatch(String regex, String content) {
        if(content == null) {
            //提供null的字符串为不匹配
            return false;
        }
        
        if(StringUtils.isEmpty(regex)) {
            //正则不存在则为全匹配
            return true;
        }
        
        return Pattern.matches(regex, content);
    }
    
    public static String find(String input, String regex) {
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(input);
        boolean result = m.find();
        if(result==false) {
            return null;
        }
        return input.substring(m.start(), m.end());
    }
    
    public static <T extends Collection<String>> T findAll(String regex, String content, int group, T collection) {
        Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
        return findAll(pattern, content, group, collection);
    }
    public static <T extends Collection<String>> T findAll(Pattern pattern, String content, int group, T collection) {
        Matcher matcher = pattern.matcher(content);
        while(matcher.find()){
            collection.add(matcher.group(group));
        }
        return collection;
    }    
    
    
    
    public static String replaceAll(String content, String regex, String replacementTemplate) {
        if(StringUtils.isEmpty(content)){
            return content;
        }
        
        final Matcher matcher = Pattern.compile(regex, Pattern.DOTALL).matcher(content);
        matcher.reset();
        boolean result = matcher.find();
        if (result) {
            final Set<String> varNums = findAll(GROUP_VAR, replacementTemplate, 1, new HashSet<String>());
            final StringBuffer sb = new StringBuffer();
            do {
                String replacement = replacementTemplate;
                for (String var : varNums) {
                    int group = Integer.parseInt(var);
                    replacement = replacement.replace("$" + var, matcher.group(group));
                }
                matcher.appendReplacement(sb, escape(replacement));
                result = matcher.find();
            } while (result);
            matcher.appendTail(sb);
            return sb.toString();
        }
        return content;
    }    
    
    public static String escape(String content) {
        if(StringUtils.isBlank(content)){
            return content;
        }
        final StringBuilder builder = new StringBuilder();
        char current;
        for(int i = 0; i < content.length(); i++) {
            current = content.charAt(i);
            if(RE_KEYS.contains(current)) {
                builder.append('\\');
            }
            builder.append(current);
        }
        return builder.toString();
    }    
    
    
}
